<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
  <title>JS Forms Demo Page</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="Author" content="Jonathan Buchanan">
  <style type="text/css">
  html { margin: 0; padding: 0; }
  body { padding: 1em 5%; font-family: sans-serif; }
  h1, h2 { color: #69c; font-family: sans-serif; border-bottom: 1px solid #000; }
  h1 { font-size: 160%; margin: 0em 0 1em -3%; }
  h2 { font-size: 140%; margin: 1em 0 1em -2%; }
  </style>
  <!-- Dependencies -->
  <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
  <script type="text/javascript" src="http://dombuilder.googlecode.com/svn/trunk/DOMBuilder.js"></script>
  <!-- js-forms -->
  <script type="text/javascript" src="util.js"></script>
  <script type="text/javascript" src="time.js"></script>
  <script type="text/javascript" src="widgets.js"></script>
  <script type="text/javascript" src="fields.js"></script>
  <script type="text/javascript" src="forms.js"></script>
  <script type="text/javascript" src="formsets.js"></script>
  <script type="text/javascript">
  SOURCE_CHOICES = [
      ["", "----------"],
      [1, "In a specialist catalogue"],
      [2, "On the internet"],
      [3, "Other"]
  ];

  CAT_SOURCE_CHOICES = [
      ["Physical Locations", [
          [1, "In a specialist catalogue"]
      ]],
      ["Virtual Locations", [
          [2, "On the internet"],
      ]],
      ["Somewhere Else Entirely", [
          [3, "Other"]
      ]]
  ];

  STUFF_CHOICES = [
      [1, "Specialist catalogues"],
      [2, "The internet"],
      [3, "The catalogues"],
      [4, "Special internets"],
      [5, "Other"]
  ];

  CAT_STUFF_CHOICES = [
      ["Animals", [
          [1, "Cats"],
          [2, "Dogs"],
      ]],
      ["Food", [
          [3, "Pizza"],
          [4, "Bananas"],
      ]]
  ];

  ContactForm = formFactory({
      fields: function()
      {
          return {
            name:
              new CharField({minLength: 1, maxLength: 100, label: "Your name"}),
            age:
              new IntegerField({minValue: 1, maxValue: 120, label: "Your age"}),
            faveFloat:
              new FloatField({minValue: 1.5, maxValue: 24.5, label: "Your favourite number between 1.5 and 24.5"}),
            faveDecimal:
              new DecimalField({maxDigits: 4, decimalPlaces: 2, label: "Your favourite decimal"}),
            phoneNumber:
              new RegexField(/\d{3}-\d{5}/, {label: "Your phone number (e.g. 555-12345)", errorMessages: {invalid: "Not a valid phone number"}}),
            email:
              new EmailField({widget: new TextInput({attrs: {maxlength: "200"}}), label: "Your email address"}),
            zeeMikrofilm:
              new FileField({label: "Please upload zee mikrofilm"}),
            photo:
              new ImageField({label: "Photo or it didn't happen"}),
            website:
              new URLField({widget: new TextInput({attrs: {size: "50"}}), label: "Your website URL"}),
            faveIPAddress:
              new IPAddressField({label: "Your favourite IP address... you freak"}),
            body:
              new CharField({widget: new Textarea(), label: "Your message"}),
            source:
              new ChoiceField({choices: SOURCE_CHOICES, label: "Where did you hear about us?"}),
            catSource:
              new ChoiceField({choices: CAT_SOURCE_CHOICES, label: "Where did you hear about us again, with feeling?"}),
            moreSource:
              new ChoiceField({choices: SOURCE_CHOICES, label: "Where did you hear about us again?", widget: new RadioSelect()}),
            stuff:
              new MultipleChoiceField({choices: STUFF_CHOICES, attrs: {size: 5}, label: "Pick stuff you like"}),
            catStuff:
              new MultipleChoiceField({choices: CAT_STUFF_CHOICES, label: "Pick more stuff you like"}),
            awesome:
              new BooleanField({label: "Check here if you are awesome!", initial: true}),
            likeMonkeys:
              new NullBooleanField({label: "Do you like monkeys?", initial: "2"}),
            intBeginningWith5:
              new ComboField({fields: [new RegexField(/^[-+]?5/), new IntegerField()], label: "Type an integer begining with 5"}),
            birthday:
              new DateField({label: "Your birthday"}),
            wokeUpAt:
              new TimeField({label: "What time did you wake up at today?"}),
            howSoonIsNow:
              new DateTimeField({initial: new Date(), label: "What time was it when this page was rendered?"}),
            againWithFeeling:
              new SplitDateTimeField({initial: new Date(), label: "Once again"}),
            checkTheBoxes:
              new MultipleChoiceField({choices: STUFF_CHOICES, attrs: {size: 5}, label: "Check stuff you like", widget: new CheckboxSelectMultiple()})
          };
      },

      cleanName: function()
      {
          if (this.cleanedData.name != "Cheese")
          {
              throw new ValidationError("Your name must be Cheese.");
          }
          return this.cleanedData.name;
      }
  });

  ContactFormFormSet = formsetFactory(ContactForm, {extra: 1, canDelete: true});

  jQuery(document).ready(function()
  {
      DOMBuilder.apply(window);

      var formset = new ContactFormFormSet({
          initial: [{
              name: "Test",
              email: "test@test.com",
              body: "Testing\n\nTesting",
              source: 2,
              stuff: [1,3],
              checkTheBoxes: [1,5]
          }]
      });

      var forms = DOMBuilder.fragment.map(formset.forms, function(form, index)
      {
          return [
            H2("Contact Form " + (index + 1)),
            TABLE(TBODY(
              TR.map(form.boundFields(), function(field)
              {
                  return [TH(field.labelTag()), TD(field.asWidget())];
              })
            ))
          ];
      });

      document.body.appendChild(forms);
  });
  </script>
</head>
<body>

<h1>JS Forms Demo Page</h1>

</body>
</html>